package com.lormann.android.infoterminal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.lormann.android.infoterminal.infogatherservice.LocalBinder;


import android.app.Activity;
import android.app.NotificationManager;
import android.content.SharedPreferences;
import android.util.Log;
import android.widget.Toast;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;

import android.os.Parcel;
import android.os.Parcelable;

public class infoterminal extends Activity {
	
	
	//create a parcelable class
	//final class means it can not be subclass anymore.
	public final static class PersionInfo implements Parcelable{
		
		String myname;
		int myage;
		int myweight;
		int myheight;
		
		public static final Parcelable.Creator<PersionInfo> CREATOR=new 
			Parcelable.Creator<PersionInfo>(){

				@Override
				public PersionInfo createFromParcel(Parcel in) {
					// TODO Auto-generated method stub
					return new PersionInfo(in);
				}

				@Override
				public PersionInfo[] newArray(int size) {
					// TODO Auto-generated method stub
					return new PersionInfo[size];
				}
			
		};
		
		public PersionInfo(){
		}
		
		private PersionInfo(Parcel in){
			readFromParcel(in);
		}

		@Override
		public int describeContents() {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public void writeToParcel(Parcel arg0, int arg1) {
			// TODO Auto-generated method stub
			arg0.writeInt(myage);
			arg0.writeInt(myweight);
			arg0.writeInt(myheight);
			arg0.writeString(myname);			
		}
		
		public void readFromParcel(Parcel arg0) {
			// TODO Auto-generated method stub
			myage=arg0.readInt();
			myweight=arg0.readInt();
			myheight=arg0.readInt();
			myname=arg0.readString();
		
		}
		
	}
	
	private NotificationManager _nm;
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		//cancel notificatoin, we cound not get right bundle extra value
		_nm=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
		
		Bundle bundle=infoterminal.this.getIntent().getExtras();
	
		try{
		if(bundle!=null){
		if(bundle.getInt("NOTIFICATION_KEY")!=0)
			{
				Log.d(TAG,"NOTIFICATION_KEY(non 0): "+bundle.getInt("NOTIFICATION_KEY"));
			//	_nm.cancel(bundle.getInt("NOTIFICATION_KEY"));
			}
		else
			Log.d(TAG,"NOTIFICATION_KEY(is 0): "+bundle.getInt("NOTIFICATION_KEY"));
		}
		else
		{
			Log.d(TAG,"NOTIFICATION_KEY(is 0): bundle is null !!!!! ");
		}
		
		
		}catch(Exception e){
			Log.d(TAG,"NOTIFICATION_KEY(exception): "+e);
		}
		
		
	
			
			//_nm.cancel(savedInstanceState.getInt("NOTIFICATION_KEY"));
		
		// link relative reference and action to view and control
		SetupActionAndReferece();
		Log.d(TAG,"OnCreate !! ");
		Toast.makeText(infoterminal.this, this.toString()+" : OnCreate !! ",
				Toast.LENGTH_SHORT).show();
		

	}
	
	private static final String TAG="InfoTerminal";
	private EditText infoText;
	protected static final int MENU_ABOUT = Menu.FIRST;
	protected static final int MENU_EXIT = Menu.FIRST + 1;
	protected static final int MENU_REPORT = Menu.FIRST + 2;
	protected static final int MENU_START_STOP_SERVICE = Menu.FIRST + 3;
	protected static final int MENU_GET_SERVICE_RANDOM_NUMBER = Menu.FIRST + 4;
	protected static final int MENU_BIND_UNBIND_SERVICE= Menu.FIRST + 5;
	protected static final int MENU_CALL_EVENT_HANDLER_SERVICE= Menu.FIRST + 6;
	protected static final int MENU_GET_SERVICE_RANDOM_NUMBER_AIDL= Menu.FIRST + 7;
	
	
	private boolean isServiceStarted=false;
	private boolean isServiceBinded=false;
	private Menu remmberMenu;//local variable used to remember menu structure for later modification.

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		// I can not use resource with chinese-word on menu
		menu.add(0, MENU_ABOUT, 0, R.string.menu_about_label);
		menu.add(0, MENU_EXIT, 0, R.string.menu_exit_label);
		menu.add(0, MENU_REPORT, 0, R.string.menu_report_label);
		
		if(isServiceStarted==false)
			menu.add(0, MENU_START_STOP_SERVICE, 0, R.string.menu_startservice_label);
		else
			menu.add(0, MENU_START_STOP_SERVICE, 0, R.string.menu_stopservice_label);
		
		menu.add(0, MENU_GET_SERVICE_RANDOM_NUMBER, 0, R.string.menu_getservicRandomNumber_label);
		menu.add(0, MENU_CALL_EVENT_HANDLER_SERVICE, 0, R.string.menu_calleventhandlerservice_label);
		menu.add(0, MENU_GET_SERVICE_RANDOM_NUMBER_AIDL, 0, R.string.menu_getservicRandomNumber_aidl_label);
		
		if(isServiceBinded==false)
			menu.add(0, MENU_BIND_UNBIND_SERVICE, 0, R.string.menu_bindservice_label);
		else
			menu.add(0, MENU_BIND_UNBIND_SERVICE, 0, R.string.menu_unbindservice_label);
		
		//local variable used to remember menu structure for later modification.
		remmberMenu=menu;
		
		return true;

	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		super.onOptionsItemSelected(item);
		switch (item.getItemId()) {
		case MENU_ABOUT:
			openAboutDialog();
			break;
		case MENU_REPORT:
			openReportActivity();
			break;
		case MENU_EXIT:
			finish();
			break;
		case MENU_START_STOP_SERVICE:
			menuStartstopAction();
			break;
			
		case MENU_BIND_UNBIND_SERVICE:
			menuBindandunbindServerAction();
			break;
		case MENU_GET_SERVICE_RANDOM_NUMBER:
			callServiceRandomNumberGenerator();
			break;
		case MENU_CALL_EVENT_HANDLER_SERVICE:
			callEventHandler_service();
			break;
		case MENU_GET_SERVICE_RANDOM_NUMBER_AIDL:
			try {
				callServiceRandomNumberGenerator_AIDL();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;
		}
		return true;
	}
	void callEventHandler_service(){
		Message msg=Message.obtain(null,infogatherservice.MSG_SERVICE_EVENT_1, 0, 0);
		try{
			serviceMessenger.send(msg);
		}catch(RemoteException e){
			e.printStackTrace();
		}
	}
	
	infogatherservice mService=null;
	Messenger serviceMessenger=null;
	
	IRemoteService mIRemoteService;
	private ServiceConnection mConnection=new ServiceConnection(){

		@Override
		public void onServiceConnected(ComponentName arg0, IBinder arg1) {
			// TODO Auto-generated method stub
			Log.d(TAG,"onServiceConnected () ");
			LocalBinder binder=(LocalBinder)arg1;
			mService=binder.getService();
			serviceMessenger=mService.getMessengerHandle();
						
			mIRemoteService=IRemoteService.Stub.asInterface(binder.getIRemoteService());
			
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			Log.d(TAG,"onServiceDisconnected () ");
			mService=null;
		}
		
		
	};
	private void callServiceRandomNumberGenerator(){
		
		Log.d(TAG,"callServiceRandomNumberGenerator () ");
		
		if(mService!=null)
		{
			int randomNum=mService.getRandomNumber();		
			Log.d(TAG,"The Random Number is : "+randomNum);
		}
		else
			Log.d(TAG,"mService is null !!!");
		
	}
	private void callServiceRandomNumberGenerator_AIDL() throws RemoteException{
		
		Log.d(TAG,"callServiceRandomNumberGenerator_AIDL () ");
		
		if(mIRemoteService!=null)
		{
			int randomNum=mIRemoteService.getRandomNumber_AIDL();		
			Log.d(TAG,"AIDL The Random Number is : "+randomNum);
		}
		else
			Log.d(TAG,"mIRemoteService is null !!!");
		
	}
	private void bindService(){
		Log.d(TAG,"bindService() ");
		//Setup connection to service
		Intent intent=new Intent(this,infogatherservice.class);
		bindService(intent,mConnection,Context.BIND_AUTO_CREATE);
		
		
	}
	private void unbindService(){
		Log.d(TAG,"unbindService() ");
		unbindService(mConnection);
	}
	private void menuBindandunbindServerAction(){
		Log.d(TAG,"menuBindandunbindServerAction () ");

		remmberMenu.removeItem(MENU_BIND_UNBIND_SERVICE);
		
		//Start or stop service here
		if(isServiceBinded==false)
			{
				isServiceBinded=true;
				bindService();
			}
		else
			{
				unbindService();
			    isServiceBinded=false;
			}
		
		//change menu appearance.
		if(isServiceBinded==false)
			remmberMenu.add(0, MENU_BIND_UNBIND_SERVICE, 0, R.string.menu_bindservice_label);
		else
			remmberMenu.add(0, MENU_BIND_UNBIND_SERVICE, 0, R.string.menu_unbindservice_label);
	}
	
	
	private void menuStartstopAction(){
		
		remmberMenu.removeItem(MENU_START_STOP_SERVICE);
		
		//Start or stop service here
		if(isServiceStarted==false)
			{
				isServiceStarted=true;
				startinfoService();
			}
		else
			{
			    stopinfoService();
				isServiceStarted=false;
			}
		
		//change menu appearance.
		if(isServiceStarted==false)
			remmberMenu.add(0, MENU_START_STOP_SERVICE, 0, R.string.menu_startservice_label);
		else
			remmberMenu.add(0, MENU_START_STOP_SERVICE, 0, R.string.menu_stopservice_label);	
		
	}
	private void openReportActivity()
	{
		Intent reportIntent=new Intent();
		reportIntent.setClass(infoterminal.this,Report.class);
		
		//create bundle for carry data to new activity
		Bundle bundle=new Bundle();
		bundle.putString("KEY_USRNAME","Lormann Chen");
		reportIntent.putExtras(bundle);
		
		startActivity(reportIntent);
	}
	private void startinfoService(){
		Intent intent=new Intent(this,infogatherservice.class);
		
		//create bundle for carry data to new activity
		Bundle bundle=new Bundle();
		bundle.putString("KEY_USRNAME","Lormann Chen");
		intent.putExtras(bundle);
		
		this.startService(intent);
	}
	private void stopinfoService(){
		Intent intent=new Intent(this,infogatherservice.class);
		this.stopService(intent);
	}

	private void SetupActionAndReferece() {

		// setup onClick action for Info request button
		Button infoReqButton = (Button) findViewById(R.id.reqButton);
		infoReqButton.setOnClickListener(infoReqAction);

		// Setup about button
		Button aboutButton = (Button) findViewById(R.id.aboutButton);
		aboutButton.setOnClickListener(aboutButtonAction);
		
		//set EditText reference
		infoText = (EditText) findViewById(R.id.infoText);
		
		//Test button Setting
		Button mainButton=(Button) findViewById(R.id.button_main);
		Button reportButton=(Button) findViewById(R.id.button_report);
		Button aboutmeButton=(Button) findViewById(R.id.button_aboutme);
		Button settingButton=(Button) findViewById(R.id.button_setting);
		
		button_action main_button_actions=new button_action(infoterminal.this);
		
		mainButton.setOnClickListener(main_button_actions.open_main_activity);
		reportButton.setOnClickListener(main_button_actions.open_report_activity);
		aboutmeButton.setOnClickListener(main_button_actions.open_aboutme_activity);
		settingButton.setOnClickListener(main_button_actions.open_setting_activity);
		
		
		//sharepreferences test
		Button savepf_Button=(Button) findViewById(R.id.button_savepf);
		Button loadpf_Button=(Button) findViewById(R.id.button_loadpf);
		savepf_Button.setOnClickListener(savepfButtonAction);
		loadpf_Button.setOnClickListener(loadpfButtonAction);
		
		
		//call logcat button ref.
		Button callLogcat_Button=(Button) findViewById(R.id.button_callLogcat);
		callLogcat_Button.setOnClickListener(CallLogcatButtonAction);
		
	}
	
	//call logcat button ref.
	private Process logcatProc;	
	private BufferedReader mReader = null;
	private OnClickListener CallLogcatButtonAction = new OnClickListener() {

		@Override
		public void onClick(View arg0) {
			//Save sharePreference
			Log.d(TAG,"Call LogCat!!!!!  ");	
			
			try {
				
				logcatProc=Runtime.getRuntime().exec(new String[]{"logcat"," -h"});
				
				//show exec. result
				mReader=new BufferedReader(new InputStreamReader(logcatProc.getInputStream()),1024);
				String line;
				while((line=mReader.readLine())!=null){
					Log.d(TAG,line);	
				}
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				Log.e("alogcat", "error reading log", e);
			}finally{
				Log.d(TAG,"End of running Call LogCat!!!!!  ");	
				if(logcatProc!=null)
					{
						logcatProc.destroy();
						logcatProc=null;
					}
					
			}

		}

	};
	
	private OnClickListener savepfButtonAction = new OnClickListener() {

		@Override
		public void onClick(View arg0) {
			//Save sharePreference
			SharedPreferences sharedPreferences=getPreferences(MODE_PRIVATE);
			SharedPreferences.Editor editor = sharedPreferences.edit();
	        editor.putString("PREF_STRING", infoText.getText().toString());
	        editor.commit();
			

		}

	};
	private OnClickListener loadpfButtonAction = new OnClickListener() {

		@Override
		public void onClick(View arg0) {
			//load sharePreference
			SharedPreferences sharedPreferences=getPreferences(MODE_PRIVATE);
			String savepf_string=sharedPreferences.getString("PREF_STRING", "");
			
			//restore saved_pf to EditText
			infoText.setText(savepf_string);
		}

	};
	private void openAboutDialog() {
		new AlertDialog.Builder(infoterminal.this)
				.setTitle(R.string.aboutTitle)
				.setMessage(R.string.aboutMessage)
				.setPositiveButton(R.string.aboutOKLabel,
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface arg0, int arg1) {

							}

						})
				.setNegativeButton(R.string.about_homepage_label,
						new android.content.DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								// Open homepage
								Uri uri = Uri
										.parse(getString(R.string.homepage_uri));
								Intent intent = new Intent(Intent.ACTION_VIEW,
										uri);
								startActivity(intent);
							}

						}).show();
	}

	private OnClickListener aboutButtonAction = new OnClickListener() {

		@Override
		public void onClick(View arg0) {
			openAboutDialog();
		}

	};
	private OnClickListener infoReqAction = new OnClickListener() {

		@Override
		public void onClick(View arg0) {

			// show info via Toast
			Toast.makeText(infoterminal.this, R.string.ToastInfoArrivedMessage,
					Toast.LENGTH_SHORT).show();

			// setup reference to EditText
			
			infoText.setText(R.string.responseInfo);

		}

	};
	
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		Log.d(TAG,"onPause !! ");
		super.onPause();		
		Toast.makeText(infoterminal.this, this.toString()+" : onPause !! ",
				Toast.LENGTH_SHORT).show();
		
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d(TAG,"onDestroy !! ");
		Toast.makeText(infoterminal.this, this.toString()+" : onDestroy !! ",
				Toast.LENGTH_SHORT).show();
	}

	@Override
	protected void onRestart() {
		// TODO Auto-generated method stub
		super.onRestart();
		Log.d(TAG,"onRestart !! ");
		Toast.makeText(infoterminal.this, this.toString()+" : onRestart !! ",
				Toast.LENGTH_SHORT).show();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		Log.d(TAG,"onResume !! ");
		Toast.makeText(infoterminal.this, this.toString()+" : onResume !! ",
				Toast.LENGTH_SHORT).show();
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		Log.d(TAG,"onStart !! ");
		Toast.makeText(infoterminal.this, this.toString()+" : onStart !! ",
				Toast.LENGTH_SHORT).show();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		Log.d(TAG,"onStop !! ");
		Toast.makeText(infoterminal.this, this.toString()+" : onStop !! ",
				Toast.LENGTH_SHORT).show();
	}
}